package com.ruoyi.utils;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author zhouzhixiong
 * @Date 2024/3/16 9:43
 */
@Component
public class BusinessService {

    @Resource
    private HistoryService historyService;

    @Resource
    private TaskService taskService;

    /**
     * 根据业务类型和BusinessKey获取对应的流程实例ID
     *
     * @param processDefinitionKey 流程定义Key
     * @param businessKey          业务Key
     */
    public String getProcessId(String processDefinitionKey, String businessKey) {
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey(processDefinitionKey)
                .processInstanceBusinessKey(businessKey)
                .singleResult();
        return processInstance != null ? processInstance.getId() : null;
    }

    /**
     * 根据业务类型和businessKey列表查询对应的流程实例ID列表(不区分是否完成)
     *
     * @param processDefinitionKey 流程定义Key，用于指定流程类型
     * @param businessKeys 业务Key列表
     */
    public List<String> queryProcessIds(String processDefinitionKey, List<String> businessKeys) {
        List<String> processInstanceIds = new ArrayList<>();

        for (String businessKey : businessKeys) {
            HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
                    .processDefinitionKey(processDefinitionKey)
                    .processInstanceBusinessKey(businessKey)
                    .singleResult();

            processInstanceIds.add(instance != null ? instance.getId() : null);
        }

        return processInstanceIds;
    }

    /**
     * 根据业务类型和用户ID（作为审批人）获取未完成的流程实例ID列表
     *
     * @param processDefinitionKey 流程定义Key
     * @param userId 用户ID
     */
    public List<String> getActiveProcessInstanceIdsByUserId(String processDefinitionKey, String userId) {
        // 查询用户作为审批人的所有活动任务
        List<String> processInstanceIds = taskService.createTaskQuery()
                .processDefinitionKey(processDefinitionKey)
                .taskAssignee(userId)
                .active() // 仅查询未完成的任务
                .list()
                .stream()
                .map(Task::getProcessInstanceId) // 获取任务所属的流程实例ID
                .distinct()
                .collect(Collectors.toList());

        return processInstanceIds;
    }

    /**
     * 根据业务类型和用户ID（作为审批人）获取已办理的流程实例ID列表
     *
     * @param processDefinitionKey 流程定义Key
     * @param userId 用户ID
     * @return 已办理的流程实例ID列表
     */
    public List<String> getCompletedProcessInstanceIdsByUserId(String processDefinitionKey, String userId) {
        // 查询用户作为审批人且已完成的任务
        List<String> completedProcessInstanceIds = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(processDefinitionKey)
                .taskAssignee(userId)
                .finished() // 查询已完成的任务
                .list()
                .stream()
                .map(HistoricTaskInstance::getProcessInstanceId) // 获取任务所属的流程实例ID
                .distinct()
                .collect(Collectors.toList());

        return completedProcessInstanceIds;
    }

    /**
     * 根据业务类型和获取流程实例ID列表不管任务是否已被处理
     *
     * @param processDefinitionKey 流程定义Key
     */
    public List<String> getAllProcessInstanceIds(String processDefinitionKey) {
        // 获取用户作为审批人参与的所有任务（不论是否已完成）对应的流程实例ID
        List<String> allProcessInstanceIds = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey(processDefinitionKey)
                .list()
                .stream()
                .map(HistoricTaskInstance::getProcessInstanceId)
                .distinct()
                .collect(Collectors.toList());
        return allProcessInstanceIds;
    }
}
